One teammate suggests converting the DNA data to a binary representation
You ponder this, as it will potentially halve the required data storage costs, but at the expense of human readability. You decide to write a module to encode and decode your data to benchmark your savings
Implement encode_nucleotide/1 to accept the code point for the nucleic acid and return the integer value of the encoded code.
Implement decode_nucleotide/1 to accept the integer value of the encoded code and return the code point for the nucleic acid.
Implement encode/1 to accept a charlist representing nucleic acids and gaps and return a bitstring of the encoded data.
Implement decode/1 to accept a bitstring representing nucleic acids and gaps and return the decoded data as a charlist.
https://exercism.org/tracks/elixir/exercises/dna-encoding
defmodule DNA do
@moduledoc """
practice bitStrings
"""
@encode_map %{ ?\s => 0b0000, ?A => 0b0001, ?C => 0b0010, ?G => 0b0100, ?T => 0b1000 }
@decode_map Enum.reduce(@encode_map, %{}, fn {dna, bitstring}, result -> Map.merge(result, %{ bitstring => dna }) end)
@spec encode_nucleotide(integer()) :: integer()
def encode_nucleotide(code_point), do: @encode_map[code_point]
@spec decode_nucleotide(integer()) :: integer()
def decode_nucleotide(encoded_code), do: @decode_map[encoded_code]
@spec encode(charlist()) :: bitstring()
def encode(dna), do: process_encode(dna, <<>>)
@spec decode(bitstring()) :: charlist()
def decode(dna), do: process_decode(dna, '')
@spec process_encode(charlist(), bitstring()) :: bitstring()
defp process_encode([], result), do: result
defp process_encode([head | tail], result), do: process_encode(tail, <<result::bitstring, encode_nucleotide(head)::4>>)
@spec process_decode(bitstring(), charlist()) :: charlist()
defp process_decode(<<>>, result), do: result
defp process_decode(<<head::4, rest::bitstring>>, result), do: process_decode(rest, result ++ [decode_nucleotide(head)])
end